package org.taobao.ibatiside.ui.wizard;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.codegen.jet.JETEmitter;
import org.eclipse.emf.codegen.jet.JETException;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.dialogs.WizardNewFileCreationPage;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.navigator.CommonNavigator;
import org.eclipse.ui.navigator.ICommonViewerMapper;
import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
import org.taobao.ibatiside.codegen.ConfigSampleModel;
import org.taobao.ibatiside.codegen.MapSampleModel;
import org.taobao.ibatiside.core.IbatisConstant;
import org.taobao.ibatiside.core.filemodel.FileProber;
import org.taobao.ibatiside.ui.util.UIHelper;
import org.taobao.ibatiside.ui.util.WorkspaceUtil;
import org.taobao.ibatiside.ui.view.BatisCommonViewerMapper;
import org.taobao.ibatiside.ui.view.BatisNavigator;
import org.taobao.ibatiside.ui.view.IbatisModelContentProvider;

public class NewConfigFileWizard extends BasicNewResourceWizard {

	private WizardNewFileCreationPage newConfig;
	private WizardNewFileCreationPage newMap;
	private IBatisVersionPage versionPage;

	public NewConfigFileWizard() {
		super();
	}

	@Override
	public void addPages() {
		super.addPages();
		newConfig = new WizardNewFileCreationPage("batis_config_xml",
				getSelection()) {
			@Override
			protected InputStream getInitialContents() {
				return configFileContent();
			}
			@Override
			protected boolean validatePage() {
					boolean is_ok = super.validatePage();
					if (is_ok){
						newMap.setContainerFullPath(newConfig.getContainerFullPath());
					}
					return is_ok;
			}
		};
		newConfig.setTitle("Configuration");
		newConfig.setAllowExistingResources(false);
		newConfig.setFileExtension("xml");
		newConfig.setDescription("create an iBATIS configuration file");
		addPage(newConfig);
		newMap = new WizardNewFileCreationPage("batis_map_xml", getSelection()) {
			public boolean canFlipToNextPage() {
				boolean result = super.canFlipToNextPage();
				if (!result)
					return result;
				IProject project = ResourcesPlugin.getWorkspace().getRoot()
						.findMember(newConfig.getContainerFullPath())
						.getProject();
				int version = FileProber.getIbatisVerion(project);
				if (version != IbatisConstant.NOT_IBATIS) {
					versionPage.setVersion(version);
					return false;
				}
				return true;
			};

			@Override
			protected InputStream getInitialContents() {
				return mapFileContent();
			}
		};
		newMap.setTitle("Mapper File");
		newMap.setDescription("Create an empty map file, a configuration file must has at least one!");
		newMap.setFileExtension("xml");
		addPage(newMap);
		versionPage = new IBatisVersionPage("batis_version");
		addPage(versionPage);
	}

	protected InputStream mapFileContent() {
		JETEmitter emitter = UIHelper.getJet("v2/map-sample.xmljet");
		MapSampleModel msm = new MapSampleModel();
		msm.setNamespace("foo");
		try {
			String content = emitter.generate(new NullProgressMonitor(),
					new Object[] { msm });
			return new ByteArrayInputStream(content.getBytes("utf-8"));
		} catch (JETException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}

	protected InputStream configFileContent() {
		JETEmitter emitter = UIHelper.getJet("v2/config-sample.xmljet");
		ConfigSampleModel csm = new ConfigSampleModel();
		IPath map_path = newMap.getContainerFullPath();
		IPath map_pkg = WorkspaceUtil.getPackageFragementPath(map_path);
		csm.add(map_pkg.append(newMap.getFileName()).toString());
		try {
			String content = emitter.generate(new NullProgressMonitor(),
					new Object[] { csm });
			return new ByteArrayInputStream(content.getBytes("utf-8"));
		} catch (JETException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public boolean canFinish() {
		return newConfig.isPageComplete() && newMap.isPageComplete();
	}

	@Override
	public void init(IWorkbench workbench, IStructuredSelection currentSelection) {
		super.init(workbench, currentSelection);
		setWindowTitle("Create iBATIS Configuration file");
		setNeedsProgressMonitor(true);
	}

	@Override
	public boolean performFinish() {
		if (versionPage.getVersion() == IbatisConstant.VERSION_MYBATIS) {
			throw new UnsupportedOperationException(
					"MyBATIS support is under construction!");
		}
		IFile map = newMap.createNewFile();
		if (map == null)
		{
			return false;
		}
		IFile file = newConfig.createNewFile();
		if (file == null) {
			return false;
		}

		selectAndReveal(file);

		// Open editor on new file.
		IWorkbenchWindow dw = getWorkbench().getActiveWorkbenchWindow();
		try {
			if (dw != null) {
				IWorkbenchPage page = dw.getActivePage();
				if (page != null) {
					IDE.openEditor(page, file, true);
				}
			}
		} catch (PartInitException e) {
			e.printStackTrace();
		}
		syncOverview(file);
		return true;
	}

	private void syncOverview(IFile file) {
		CommonNavigator overview = (CommonNavigator) getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(BatisNavigator.VIEW_ID);
		if (overview != null){
			BatisCommonViewerMapper viewer_mapper = (BatisCommonViewerMapper) overview.getCommonViewer().getMapper();
			Object element = viewer_mapper.getWrapper(file.getProject());
			if (element != null){
				overview.getCommonViewer().refresh(element);
			}
		}
	}

}
